package com.zs.blog.extension.condition.query;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;

/**
 * @Title: EnhanceLambdaQueryWrapper
 * @Author zs
 * @Package com.zs.blog.extension.condition.query
 * @Date 2025/10/13 20:25
 * @description: LambdaQueryWrapper增强类
 */
public class EnhanceLambdaQueryWrapper<T> extends LambdaQueryWrapper<T> {

    /**
     * 带有表别名的eq
     *
     * @param tableAlias 表别名
     * @param column     字段方法
     * @param value      字段值
     * @return this
     */
    public EnhanceLambdaQueryWrapper<T> eqWithTableAlias(String tableAlias, SFunction<T, ?> column, Object value) {
        if (value != null) {
            // 解析方法名
            LambdaMeta lambdaMeta = LambdaUtils.extract(column);
            String methodName = lambdaMeta.getImplMethodName();
            // 处理方法名
            String property = methodName.replace("get", "");
            // 解析驼峰命名的属性
            List<String> words = splitCamelCase(property);
            // 组合数据库字段
            StringJoiner joiner = new StringJoiner("_");
            words.forEach(joiner::add);
            String columnName = joiner.toString();
            String fullName = tableAlias + "." + columnName;
            // 设置SQL片段
            super.apply(fullName + "={0}", value);
        }
        return this;
    }

    /**
     * 辅助方法: 分裂驼峰命名的单词
     *
     * @param camelCaseWord 驼峰命名的单词
     * @return 分裂好的单词列表
     */
    protected List<String> splitCamelCase(String camelCaseWord) {
        if (camelCaseWord == null) {
            return null;
        }
        String[] result = camelCaseWord.split("(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[0-9])(?=[A-Za-z])|(?<=[A-Za-z])(?=[0-9])");

        List<String> splitWords = new ArrayList<>();
        for (String s : result) {
            String lowerCaseWord = s.toLowerCase();
            splitWords.add(lowerCaseWord);
        }
        return splitWords;
    }
}
